import {
  Component, OnInit, Input, ChangeDetectorRef, ChangeDetectionStrategy,
  HostListener, ElementRef, ViewChild, Output, EventEmitter
} from '@angular/core';
import { FormBuilder, FormGroup } from '@angular/forms';
import { SearchService, SearchType } from '../search.service';
import { CompanyService } from '../../../../modules/research/company/company.service';
import { Subscription } from 'rxjs';

@Component({
  selector: 'app-company-search',
  templateUrl: './company-search.component.html',
  styleUrls: ['./company-search.component.scss'],
  changeDetection: ChangeDetectionStrategy.OnPush,
  providers: [SearchService]
})
export class CompanySearchComponent implements OnInit {
  private searchSub: Subscription;
  private closeSub: Subscription;

  @ViewChild('searchField') searchField: ElementRef;

  @Input() searchType: SearchType;
  @Input() hasAddButton = false;
  @Input() placeholder = 'Find a company by name or identifier';
  @Input() navigationId: string = "searchInput";
  @Output() companyAdded: EventEmitter<string> = new EventEmitter();

  public searchForm: FormGroup;
  private skip = 0;
  private take = 20;
  private searchResults = [];
  public showResults = false;
  public checkSearchType: any = SearchType;
  public downloadLinks = [];

  constructor(
    private fb: FormBuilder,
    private searchService: SearchService,
    private companyService: CompanyService,
    private cdRef: ChangeDetectorRef
  ) {
    this.initForm();
  }

  ngOnInit() { }

  ngOnDestroy(){
    if(this.searchSub) this.searchSub.unsubscribe();
    if(this.closeSub) this.closeSub.unsubscribe();
  }

  @HostListener('document:click', ['$event']) onDocumentClick(e) {

    if( !(e.target.classList.contains("link")) && !(e.target.classList.contains("result-section")) && (this.navigationId==='searchInput') ){
      if ((e.target.id === this.navigationId)&&(this.showResults===false)){
          this.showResults = true;
      } else if ((e.target.id !== this.navigationId)&&(this.showResults===true)){
        this.showResults = false;
      }
    }

    if (e.target.className instanceof Array && e.target.className.indexOf('download-link') === -1) {
      if (this.searchForm.get('term').value === '') {
        this.showResults = false;
        this.searchResults = [];
        this.skip = 0;
        this.take = 20;
      }
      else
        this.showResults = this.searchResults.length > 0 && (this.searchField.nativeElement as HTMLElement).contains(e.target);

        if (this.searchResults.length === 0 && this.searchType !== SearchType.portfolio) {
        this.searchForm.get('term').setValue('');
      }
    }
  }

  get term() {
    return this.searchForm.get('term').value;
  }

  get id(): string {
    return this.searchForm.get('id') === null ? "" : this.searchForm.get('id').value;
  }

  private initForm() {
    this.searchForm = this.fb.group({
      'term': [''],
      'id': ['']
    });

    let change =  this.searchForm.get('term').valueChanges;

    this.closeSub = change.subscribe(term=>{
      if(term == "") {
        this.showResults = false;
        this.searchResults = [];
      }
    });

    this.searchSub = change
      .filter(term => term)
      .debounceTime(400)
      .distinctUntilChanged()
      .switchMap(term => this.searchService.search(this.searchType, term, this.skip, this.take))
      .subscribe(results => this.handleResults(results));
  }

  private scroll(event) {
    if (this.searchResults.length === this.take
      && event.currentTarget.scrollHeight === event.currentTarget.scrollTop + event.currentTarget.offsetHeight) {
      this.skip += this.take;
      this.searchService.search(this.searchType, this.searchForm.get('term').value, this.skip, this.take)
        .subscribe(results => this.handleResults(results, true));
    }
  }

  private handleResults(results, append = false) {
    this.searchResults = append ? this.searchResults.concat(results) : results;
    this.showResults = this.searchForm.get('term').value !== '';
    this.cdRef.markForCheck();
  }

  public itemNameSelected(id: string, name: string) {
    this.searchForm.setValue({ id: id, term: name }, { emitEvent: false});
    this.showResults = false;
  }

  public addCompanyClicked(companyId: string) {
    this.companyAdded.emit(companyId);
    this.searchForm.get('term').setValue('');
  }

  public clearAndFocusInput(){
    this.searchForm.get('term').setValue('');
    setTimeout(()=>{  
      this.searchField.nativeElement.focus();
    });
  }

}
